import { BrowserWindow } from 'electron'
import store from './store'
import { delWindow, getWindow, saveWindow } from './windowProxy'
import { join } from 'path'
import { is } from '@electron-toolkit/utils'
import wsClient from './wsClient'
import ADB from './db/ADB'
import Server from './server'
import FileUtils from './fileUtils'

const NODE_ENV = process.env.NODE_ENV

const loginWinWidth = 300
const loginWinHeight = 400
const registerWinWidth = 300
const registerWinHeight = 500
const restPasswordWinWidth = 300
const restPasswordWinHeight = 450
const mainWinWidth = 1200
const mainWinHeight = 800
/**
 * 登录成功
 *
 * 该函数用于处理登录成功的操作，如设置窗口大小、居中显示等。
 * 主要目的是为了提供登录成功的操作功能，如设置窗口大小、居中显示等。
 *
 * @param {IpcMainEvent} event - 窗口对象
 * @param {BrowserWindow} mainWindow - 窗口对象
 * @param {userInfo:{
 *   userId:string,
 *   admin:string,
 *   nickname:string,
 *   avatar:string,
 *   areaCode:string,
 *   areaName:string,
 *   contactStatus:string,
 *   email:string,
 *   joinType:number,
 *   nickName:string,
 *   personalSignature:string,
 *   sex:number,
 *   token:string,
 *   userSweetCircleId:string},wsIp:string} data - 登录成功后的用户信息
 */
const loginSuccess = (event, mainWindow, data) => {
  const wsIp = data.wsIp
  data = data.userInfo
  mainWindow.setResizable(true) // 设置窗口可以改变
  mainWindow.setSize(mainWinWidth, mainWinHeight) // 设置窗口大小
  mainWindow.center() // 设置窗口居中显示
  mainWindow.setMinimumSize(800, 600) // 设置窗口最小尺寸
  store.setData(data.userId, data) // 设置用户信息保存到主进程中
  store.setUserId(data.userId) // 设置用户ID保存到主进程中
  ADB.init() // 初始化数据库
  FileUtils.init(data.userId)
  wsClient.initWs({ token: data.token }, event.sender, wsIp) // 初始化WebSocket客户端
  Server.startLocalServer() //  启动本地服务器

  // dialog.showOpenDialog({
  //     properties: ['openFile'],
  //   }).then(result => {
  //     console.log('Selected files:', result.filePaths);
  //     console.log('Selected bookmarks:', result.bookmarks);
  //   }).catch(err => {
  //     console.error('Error opening dialog:', err);
  //   });
}

/**
 * 窗口标题栏操作
 *
 * 该函数用于处理窗口标题栏的操作，如关闭、最小化、最大化等。
 * 主要目的是为了提供窗口标题栏的操作功能，如窗口的关闭、最小化、最大化等。
 *
 * @param {BrowserWindow} win - 窗口对象
 * @param {string} action - 操作类型，如'close'、'minimize'、'maximize'等
 * @param {Object} data - 操作数据，如窗口是否最大化等
 */
const winTitleOp = (win, action, data) => {
  switch (action) {
    case 'close':
      if (data.closeType === 0) {
        win.close()
      } else {
        win.setSkipTaskbar(true) // 使窗口不显示在任务栏中
        win.hide()
      }
      break
    case 'minimize':
      win.minimize()
      break
    case 'maximize':
      win.maximize()
      break
    case 'unmaximize':
      win.setFullScreen(false)
      win.center()
      // win.setSize(maa, 600)
      // win.center()
      break
    case 'top':
      win.setAlwaysOnTop(data.top)
      break
  }
}

/**
 * 切换窗口大小
 *
 * 该函数用于切换窗口的大小，如登录窗口、注册窗口、重置密码窗口等。
 * 主要目的是为了提供窗口的切换功能，如登录窗口、注册窗口、重置密码窗口等。
 *
 * @param {BrowserWindow} mainWindow - 窗口对象
 * @param {number} isLogin - 是否是登录窗口
 */
const switchWindow = (mainWindow, isLogin) => {
  mainWindow.setResizable(true)
  if (isLogin === 0) {
    mainWindow.setSize(loginWinWidth, loginWinHeight)
  } else if (isLogin === 1) {
    mainWindow.setSize(registerWinWidth, registerWinHeight)
  } else if (isLogin === 2) {
    mainWindow.setSize(restPasswordWinWidth, restPasswordWinHeight)
  }
  mainWindow.setResizable(false)
}

/**
 * 打开或显示一个窗口。如果窗口已经存在，则显示该窗口；如果窗口不存在，则创建一个新窗口并加载指定路径的内容。
 *
 * @param {Object} params - 包含窗口配置和回调函数的对象。
 * @param {string} params.windowId - 窗口的唯一标识符，用于查找或保存窗口实例。
 * @param {string} params.title - 窗口的标题。
 * @param {number} params.weight - 窗口的宽度。
 * @param {number} params.height - 窗口的高度。
 * @param {string} params.path - 窗口加载内容的路径或哈希值。
 * @param {Function} params.callback - 窗口显示或创建成功后执行的回调函数。
 */
const openWindow = ({ windowId, title, weight, height, path, callback }) => {
  // 尝试获取已存在的窗口实例
  let win = getWindow(windowId)

  // 如果窗口不存在，则创建一个新窗口
  if (!win) {
    win = new BrowserWindow({
      icon: join(__dirname, '../../resources/sweetcircle-ico.png'), // 直接使用路径
      width: weight,
      height: height,
      autoHideMenuBar: true,
      resizable: false,
      titleBarStyle: 'hidden',
      frame: true,
      transparent: true,
      hasShadow: false,
      backgroundColor: '#ffffff',
      webPreferences: {
        preload: join(__dirname, '../preload/index.js'),
        sandbox: false,
        contextIsolation: false
      }
    })

    // 保存新创建的窗口实例
    saveWindow(windowId, win)

    // 根据开发环境加载不同的URL或文件
    if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
      win.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/index.html#${path}`).then()
    } else {
      win.loadFile(join(__dirname, `../renderer/index.html`), { hash: `${path}` }).then()
    }

    // 在开发环境下打开调试工具
    if (NODE_ENV === 'development') {
      win.webContents.openDevTools()
    }

    // 当窗口准备好显示时，设置窗口标题并显示窗口
    win.on('ready-to-show', () => {
      win.setTitle(title)
      win.show()
    })

    // 窗口首次显示时执行回调函数
    win.once('show', () => {
      callback()
    })

    // 窗口关闭时删除窗口实例
    win.on('closed', () => {
      delWindow(windowId)
    })
  } else {
    // 如果窗口已存在，则显示窗口并执行回调函数
    win.show()
    win.setSkipTaskbar(false)
    callback()
  }
}

/**
 * 更新用户信息
 */
const updateUserInfo = (config) => {
  const win = getWindow('main') // 获取 main 主窗口
  win.webContents.send('updateUserInfoB', { type: config.type, data: config.data })
}

/**
 * 退出登录
 *
 * 该函数用于退出登录，并重置窗口大小。
 * 主要目的是为了提供退出登录的功能，并重置窗口大小。
 *
 * @param {BrowserWindow} mainWindow - 窗口对象
 */
const loginOut = (mainWindow) => {
  mainWindow.setResizable(true)
  mainWindow.setMinimumSize(loginWinWidth, loginWinHeight)
  mainWindow.setSize(loginWinWidth, loginWinHeight)
  mainWindow.center()
  mainWindow.setResizable(false)
  wsClient.closeWs()
  Server.closeLocalServer()
  const fileManage = getWindow('fileManage')
  if (fileManage) {
    fileManage.close()
  }
  const setting = getWindow('setting')
  if (setting) {
    setting.close()
  }
}

// /**
//  *
//  * @param {IpcMainEvent}event
//  * @returns {Promise<void>}
//  */
// const a = (event) => {
//   /*
//     openFile: 允许用户选择一个或多个文件。
//     openDirectory: 允许用户选择一个目录。
//     multiSelections: 允许多选文件或目录。
//     showHiddenFiles: 显示隐藏文件。
//     createDirectory: 允许用户创建新目录。
//     promptToCreate: 当用户尝试打开不存在的文件时，提示用户创建新文件。
//     noResolveAliases: 不解析别名，直接显示别名目标。
//     treatPackageAsDirectory: 将包文件（如 .app）作为目录处理。
//     dontAddToRecent: 不将选择的文件添加到最近使用的列表中。
//     */
//
//   dialog
//     .showOpenDialog({
//       properties: ['openFile', 'dontAddToRecent']
//     })
//     .then((result) => {
//       event.sender.send('addSendMessageFileB', { status: 'success', data: result })
//     })
//     .catch((err) => {
//       console.error('Error opening dialog:', { status: 'fail', data: err })
//     })
// }
/**
 * 保存离线消息
 * @param event
 * @param mainWindow
 * @param {Array} data 消息列表[
 *             {
 *                 "messageId": 消息id,
 *                 "messageType":消息类型 ,
 *                 "messageCode":消息代码 ,
 *                 "messageContent": 消息内容,
 *                 "sessionId": 会话id,
 *                 "sendUserId": 发送消息者用户id,
 *                 "sendTime": 发送时间,
 *                 "contactId": 联系人id 接收消息者用户id,
 *                 "groupId": 群聊id,
 *                 "fileSize": 文件大小,
 *                 "fileName": 文件名称,
 *                 "fileType": 文件类型,
 *                 "sendStatus": 发送状态 1 接收 2未接收.未读,
 *                 "status":状态 1 正常 2 已删除
 *             }
 *         ]
 */
const saveOfflineMessages = async (event, mainWindow, data) => {
  let bol = false
  if (data.length === 0) {
    return true
  }
  // 获取所有会话列表
  let chatSessionList = await ADB.getChatSessionList()
  for (let i = 0; i < data.length; i++) {
    /*
    chatMessage: {
      messageId: 'message_id',
      messageType: 'message_type',
      messageCode: 'message_code',
      messageContent: 'message_content',
      sessionId: 'session_id',
      sendUserId: 'send_user_id',
      sendTime: 'send_time',
      contactId: 'contact_id',
      groupId: 'group_id',
      fileSize: 'file_size',
      fileName: 'file_name',
      fileType: 'file_type',
      sendStatus: 'send_status',
      status: 'status'
    },
    */
    // 消息对象
    let message = data[i]
    let session = false
    if (chatSessionList.length > 0) {
      session = chatSessionList.some((item) => {
        if (item.sessionId === message.sendUserId) {
          return item
        }
      })
    }
    // 不存在会话
    if (!session) {
      let session2 = {}
      if (message.messageCode === 1) {
        // 用户私聊
        session2 = {
          sessionId: message.sendUserId,
          sessionType: message.messageCode,
          userId: store.getUserId(),
          contactId: message.sendUserId,
          contactList: null,
          lastMessage: null,
          lastReceiveTime: null,
          noReadCount: 0,
          topType: -1,
          status: 1
        }
      } else {
        // todo 群聊  设置群聊会话信息
      }

      // 创建新的会话 保存在数据库
      bol = await ADB.addChatSession(session2)
    }
    // 修改消息信息 并保存  将对方的消息信息修改为我的消息消息信息
    message.sessionId = message.sendUserId
    message.groupId = message.sendUserId

    bol = await ADB.addChatMessage(message)
  }
  return bol
}
/**
 * 获取所有聊天会话的详细信息，包括每个会话的未读消息数量及消息列表。
 * @returns {Array} 返回一个包含所有聊天会话详细信息的数组
 */
// const getAllChatSession = async () => {
//   return await ADB.getChatSessionList()
//   // // 获取所有聊天会话的基本信息列表
//   // let list = await ADB.getChatSessionList()
//   //
//   // // 遍历每个会话，获取其详细信息
//   // for (let i = 0; i < list.length; i++) {
//   //   let session = list[i]
//   //
//   //   // 获取当前会话的消息列表
//   //   let list2 = await ADB.getChatMessageList(session.sessionId)
//   //
//   //   // 计算当前会话的未读消息数量
//   //   let noReadCount = 0
//   //   list2.forEach((item) => {
//   //     if (item.sendUserId !== store.getUserId() && item.sendStatus === 2) {
//   //       noReadCount++
//   //     }
//   //   })
//   //
//   //   // 将未读消息数量和消息列表添加到会话对象中
//   //   session.noReadCount = noReadCount
//   //   session.chatMessageList = list2
//   //   list[i] = session
//   // }
//   //
//   // // 返回包含所有会话详细信息的列表
//   // return list
// }


const getExpressPort = () => {
  return store.getExpressPort()
}

const saveFileMessage = (fileName, messageType, userId, sendUserId, token) => {
  FileUtils.savaFile(fileName, messageType, userId, sendUserId, token)
}


export default {
  loginSuccess,
  switchWindow,
  winTitleOp,
  openWindow,
  updateUserInfo,
  loginOut,
  saveOfflineMessages,
  getExpressPort,
  saveFileMessage,
  // getAllChatSession
}
